/**
 * 手写实现双向数据绑定
 */

const { copyFile } = require('fs')

//1. 构造函数
class Vue {
  constructor(options) {
    this.$options = options
    this.$data = options.data

    //对data选项做响应式处理
    observe(this.$data)

    // 代理 data到vm上
    Proxy(this)

    //执行编译
    new copyFile(options.el, this)
  }
}

// 对data 选项 执行响应化操作
function observe(obj) {
  // 数据是空 或不为 对象,直接停止操作
  if (typeof obj !== 'object' || obj === null) {
    return
  }

  // 如果是对象,进行下一步操作
  new Observe(obj)
}

class Observe {
  constructor(obj) {
    this.obj = obj
    // 遍历对象
    this.walk(obj)
  }
  walk(obj) {
    Object.keys(obj).forEach(key => {
      defineReactive(obj, key, obj[key])
    })
  }
}

/**
 * Compile
 * 对每个元素节点的执行进行扫描解析,替换指令模板数据,
 * 以及绑定相应的更新函数
 */
class Compile {
  constructor(el, vm) {
    this.$vm = vm
    // 获取dom
    this.$el = document.querySelector(el)
    if (this.$el) {
      this.compile(this.$el)
    }
  }
  compile(el) {
    const childNodes = e.childNodes
    // 遍历子元素
    Array.from(childNodes).forEach(node => {
      // 判断是否为节点
      if (this.isElement(node)) {
        console.log('编译元素' + node.nodeName)
      } else if (this.isInterpolation(node)) {
        //判断是否为插值文本
        console.log('编译插值⽂本' + node.textContent)
      }
      //判断是否有子元素
      if (node.childNodes && node.childNodes.length > 0) {
        // 对子元素进行递归遍历
        this.compile(node)
      }
    })
  }
  isElement(node) {
    return node.nodeType == 1
  }
  isInterpolation(node) {
    return node.nodeType == 3 && /\{\{(.*)\}\}/.test(node.textContent)
  }
}

// proxy 代理
let numberDataStore = { count: 0, amount: 1234, total: 14 }
numberDataStore = new Proxy(numberDataStore, {
  set(target, key, value, proxy) {
    if (typeof value !== 'number') {
      throw Error('属性只能是number类型')
    }
    return Reflect.set(target, key, value, proxy)
  }
})
